/*
Java board game library.
Copyright (C) 2011  Deepesh Garg

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

package d.g.boardgames.chess;

import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.List;

import d.g.boardgames.GameData;
import d.g.boardgames.GameListener;
import d.g.boardgames.MoveData;


public class ChessGameAnalyser {
	private PositionAnalyser positionAnalyser;
	GameData<ChessBoard, ChessMove> gameData;
	AnalyserThread at;
	Thread t;
	private boolean keepRunning = false;
	private List<AnalysisListener> analysisListenerList = new ArrayList<AnalysisListener>();

	public ChessGameAnalyser (PositionAnalyser positionAnalyser) {
		this.positionAnalyser = positionAnalyser;
	}

	public void setGameData (GameData<ChessBoard, ChessMove> gameData) {
		this.gameData = gameData;
	}
	
	public void startAnalysis () {
		if (at != null) {
			at.keepRunning = false;
			t.interrupt();
		}
		at = new AnalyserThread();
		t = new Thread(at);
		t.start();
	}
	
	public void startAnalysis (GameData<ChessBoard, ChessMove> gameData) {
		if (this.gameData != gameData) {
			this.gameData = gameData;
			if (at != null) {
				at.keepRunning = false;
				t.interrupt();
			}
			at = new AnalyserThread();
			t = new Thread(at);
			t.start();
		}
	}

	public void stopAnalysis () {
		if (at != null) {
			at.keepRunning = false;
			t.interrupt();
		}
	}

	class AnalyserThread implements Runnable {
		public boolean keepRunning = true;
		public void run() {
			while(keepRunning) {
				try {
					if (gameData != null) {
						for (MoveData<ChessBoard, ChessMove> moveData: gameData.getMoveDataList()) {
							if (!keepRunning) {
								break;
							}
							ChessBoard chessBoard = moveData.getBoard();
							if (chessBoard != null &&
								(chessBoard.getAnalysisData() == null)) {
								AnalysisData analysisData = positionAnalyser.analyse(chessBoard);
								chessBoard.setAnalysisData(analysisData);
								updateListeners();
							}
						}
					}
					try {Thread.sleep(1000);} catch (Exception e) {}
				} catch (ConcurrentModificationException cme) {
					;
				}
			}
		}
	}
	
	public void addAnalysisListener (AnalysisListener analysisListener) {
		analysisListenerList.add(analysisListener);
	}

	public void updateListeners () {
		if (analysisListenerList != null) {
			for (AnalysisListener analysisListener: analysisListenerList) {
				analysisListener.onAnalysisUpdate((ChessGameData)gameData);
			}
		}
	}
}
